﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Linq;
using Windows.Web.Syndication;
using Windows.Storage;
using Windows.Storage.Streams;
using System.IO;

namespace Channel9
{
    // FeedData
    // Holds info for a single blog feed, including a list of blog posts (FeedItem)
    public class FeedData
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public DateTime PubDate { get; set; }

        private List<FeedItem> _Items = new List<FeedItem>();
        public List<FeedItem> Items
        {
            get
            {
                return this._Items;
            }
        }
    }

    // FeedItem
    // Holds info for a single blog post
    public class FeedItem
    {
        public string Title { get; set; }
        public string Author { get; set; }
        public string Content { get; set; }
        public DateTime PubDate { get; set; }
        public Uri Link { get; set; }
        public string Thumbnail { get; set; }
        public Uri Media { get; set; }
    }

     // FeedDataSource
    // Holds a collection of blog feeds (FeedData), and contains methods needed to
    // retreive the feeds.
    public class FeedDataSource
    {
        private ObservableCollection<FeedData> _Feeds = new ObservableCollection<FeedData>();
        public ObservableCollection<FeedData> Feeds
        {
            get
            {
                return this._Feeds;
            }
        }

        public async Task GetChannel9FeedAsync()
        {  
            Task<FeedData> feed = GetFeedAsync("http://channel9.msdn.com/Feeds/RSS");
            
            this.Feeds.Add(await feed);
        }

   
        private async Task<FeedData> GetFeedAsync(string feedUriString)
        {
            System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
            client.MaxResponseContentBufferSize = 196608;
            
            bool IsOnline = true;
            
            if (!IsOnline)
            {
                try
                {
                    // Read a file from AppData
                    StorageFolder localFolder = ApplicationData.Current.LocalFolder;
                    StorageFile localFile = await localFolder.GetFileAsync("channel9cache.txt");
                    IRandomAccessStream readStream = await localFile.OpenAsync(FileAccessMode.Read);
                    IInputStream inputStream = readStream.GetInputStreamAt(0);
                    DataReader dataReader = new DataReader(inputStream);
                    uint numBytesLoaded = await dataReader.LoadAsync((uint)readStream.Size);
                    string feedText = dataReader.ReadString(numBytesLoaded);
                   
                    FeedData feedData = CreateFeedDataFromString(feedText);

                    return feedData;
                }
                catch (FileNotFoundException)
                {

                }
            }
            
            try
            {
                var result = await client.GetStringAsync(feedUriString);
                CacheFeed(result);

                FeedData feedData = CreateFeedDataFromString(result);

                return feedData;
            }
            catch (Exception)
            {
                return null;
            }
        }

        private async void CacheFeed(string feedText)
        {
            var localFolder = ApplicationData.Current.LocalFolder;
            StorageFile sampleFile = await localFolder.CreateFileAsync("channel9cache.txt", CreationCollisionOption.ReplaceExisting);
            IRandomAccessStream writeStream = await sampleFile.OpenAsync(FileAccessMode.ReadWrite);
            IOutputStream outputStream = writeStream.GetOutputStreamAt(0);
            DataWriter dataWriter = new DataWriter(outputStream);
            dataWriter.WriteString(feedText);

            await dataWriter.StoreAsync();
            outputStream.FlushAsync();
        }

        private static FeedData CreateFeedDataFromString(string result)
        {
            var doc = XDocument.Parse(result);
            var channel = doc.Descendants(XName.Get("channel"));
            FeedData feedData = new FeedData();
            feedData.Title = channel.Descendants(XName.Get("title")).First().Value;
            if (channel.Descendants(XName.Get("description")).First().Value != null)
            {
                feedData.Description = doc.Descendants(XName.Get("description")).First().Value;
            }

            foreach (var item in channel.Descendants(XName.Get("item")))
            {
                FeedItem feedItem = new FeedItem();
                feedItem.Title = item.Descendants(XName.Get("title")).Single().Value;
                feedItem.PubDate = DateTime.Parse(item.Descendants(XName.Get("pubDate")).Single().Value);
                //feedItem.Author = item.Descendants(XName.Get("Link")).Skip(1).First().Attribute("href").Value,
                feedItem.Content = item.Descendants(XName.Get("description")).Single().Value;
                feedItem.Link = new Uri(item.Descendants(XName.Get("link")).First().Value);
                //feedItem.Thumbnail = new Uri(item.Descendants(XName.Get("thumbnail", "http://search.yahoo.com/mrss/")).First().Attribute("url").Value,UriKind.Absolute);
                feedItem.Thumbnail = item.Descendants(XName.Get("thumbnail", "http://search.yahoo.com/mrss/")).First().Attribute("url").Value;
                // var media = item.Descendants(XName.Get("content", "http://search.yahoo.com/mrss/")).Where(x => x.Attribute("medium").Value == "video").FirstOrDefault();
                // if (media != null)
                //     feedItem.Media = new Uri(media.Attribute("url").Value, UriKind.Absolute);

                var media = item.Descendants(XName.Get("enclosure")).FirstOrDefault();
                if (media != null)
                    feedItem.Media = new Uri(media.Attribute("url").Value, UriKind.Absolute);


                feedData.Items.Add(feedItem);
            }
            return feedData;
        }       
    }
}

